{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Assignment 02 Spatial and Spatio-Temporal Data Processing\n",
    "\n",
    "In this assignment, you will learn how to conduct a simple multi-dimensional data analysis in Python. We use the NBA statistics collected from https://www.nbastuffer.com/2024-2025-nba-player-stats/ as our database.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('nbastat_20242025.csv')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task 1: Sort the players by the EFF (NBA's efficiency rating) (5%)\n",
    "\n",
    "NBA's efficiency rating: $(PTS + REB + AST + STL + BLK − ((FGA − FGM) + (FTA − FTM) + TO))$\n",
    "\n",
    "In our excel file, $FTM=FTA*FT\\%$, $FGA = 2PA+3PA$, and $FGM=2PA*2P\\%+3PA*3P\\%$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "vscode": {
     "languageId": "ruby"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>NAME</th>\n",
       "      <th>EFF</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>Anthony Davis</td>\n",
       "      <td>41.002</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>146</th>\n",
       "      <td>Daeqwon Plowden</td>\n",
       "      <td>12.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>149</th>\n",
       "      <td>Moses Brown</td>\n",
       "      <td>11.594</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>337</th>\n",
       "      <td>Mitchell Robinson</td>\n",
       "      <td>11.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>314</th>\n",
       "      <td>Ben Simmons</td>\n",
       "      <td>7.591</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>Trae Young</td>\n",
       "      <td>-622.136</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>40</th>\n",
       "      <td>Jalen Green</td>\n",
       "      <td>-624.342</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>Cade Cunningham</td>\n",
       "      <td>-626.171</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Jayson Tatum</td>\n",
       "      <td>-658.110</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Anthony Edwards</td>\n",
       "      <td>-699.906</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>607 rows × 2 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                  NAME      EFF\n",
       "11       Anthony Davis   41.002\n",
       "146    Daeqwon Plowden   12.000\n",
       "149        Moses Brown   11.594\n",
       "337  Mitchell Robinson   11.000\n",
       "314        Ben Simmons    7.591\n",
       "..                 ...      ...\n",
       "28          Trae Young -622.136\n",
       "40         Jalen Green -624.342\n",
       "14     Cade Cunningham -626.171\n",
       "5         Jayson Tatum -658.110\n",
       "4      Anthony Edwards -699.906\n",
       "\n",
       "[607 rows x 2 columns]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Step 1: Calculate FTM, FGA, and FGM\n",
    "df['FTM'] = df['FTA'] * df['FT%']\n",
    "df['FGA'] = df['2PA'] + df['3PA']\n",
    "df['FGM'] = (df['2PA'] * df['2P%']) + (df['3PA'] * df['3P%'])\n",
    "\n",
    "# Step 2: Calculate EFF\n",
    "df['EFF'] = (df['PpG'] + df['RpG'] + df['ApG'] + df['SpG'] + df['BpG'] - \n",
    "             ((df['FGA'] - df['FGM']) + (df['FTA'] - df['FTM']) + df['TOpG']))\n",
    "\n",
    "# Step 3: Sort players by EFF\n",
    "df_sorted = df.sort_values(by='EFF', ascending=False)\n",
    "\n",
    "# Display the sorted dataframe\n",
    "df_sorted[['NAME', 'EFF']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task 2: Find the skyline players using PTS, REB, and AST (10%)\n",
    "- To find a skyline with a naive method, you may simply iterate the data by a nested for loop;\n",
    "\n",
    "````\n",
    "Skyline:={}\n",
    "for point p in Dataset:\n",
    "    if p is not dominated by any point in Skyline:\n",
    "        Add p to Skyline;\n",
    "        Eliminate points in the Skyline that are dominated by p;\n",
    "````"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>NAME</th>\n",
       "      <th>PpG</th>\n",
       "      <th>RpG</th>\n",
       "      <th>ApG</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Shai Gilgeous-Alexander</td>\n",
       "      <td>32.3</td>\n",
       "      <td>5.2</td>\n",
       "      <td>6.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Giannis Antetokounmpo</td>\n",
       "      <td>30.9</td>\n",
       "      <td>12.1</td>\n",
       "      <td>5.9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Nikola Jokic</td>\n",
       "      <td>29.1</td>\n",
       "      <td>12.7</td>\n",
       "      <td>10.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>Anthony Davis</td>\n",
       "      <td>26.0</td>\n",
       "      <td>16.0</td>\n",
       "      <td>7.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>Trae Young</td>\n",
       "      <td>23.8</td>\n",
       "      <td>3.1</td>\n",
       "      <td>11.4</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                       NAME   PpG   RpG   ApG\n",
       "0   Shai Gilgeous-Alexander  32.3   5.2   6.1\n",
       "1     Giannis Antetokounmpo  30.9  12.1   5.9\n",
       "2              Nikola Jokic  29.1  12.7  10.5\n",
       "11            Anthony Davis  26.0  16.0   7.0\n",
       "28               Trae Young  23.8   3.1  11.4"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def is_dominated(p1, p2):\n",
    "    return all(p1[dim] <= p2[dim] for dim in ['PpG', 'RpG', 'ApG']) and any(p1[dim] < p2[dim] for dim in ['PpG', 'RpG', 'ApG'])\n",
    "\n",
    "skyline = []\n",
    "\n",
    "for _, player in df.iterrows():\n",
    "    dominated = False\n",
    "    to_remove = []\n",
    "    for s in skyline:\n",
    "        if is_dominated(player, s):\n",
    "            dominated = True\n",
    "            break\n",
    "        if is_dominated(s, player):\n",
    "            to_remove.append(s)\n",
    "    if not dominated:\n",
    "        skyline.append(player)\n",
    "        for s in to_remove:\n",
    "            skyline.remove(s)\n",
    "\n",
    "skyline_df = pd.DataFrame(skyline)\n",
    "skyline_df[['NAME', 'PpG', 'RpG', 'ApG']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task 3: Find the skyline players using PTS, REB, AST, STL, and BLK (5%)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>NAME</th>\n",
       "      <th>PpG</th>\n",
       "      <th>RpG</th>\n",
       "      <th>ApG</th>\n",
       "      <th>SpG</th>\n",
       "      <th>BpG</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Shai Gilgeous-Alexander</td>\n",
       "      <td>32.3</td>\n",
       "      <td>5.2</td>\n",
       "      <td>6.1</td>\n",
       "      <td>1.9</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Giannis Antetokounmpo</td>\n",
       "      <td>30.9</td>\n",
       "      <td>12.1</td>\n",
       "      <td>5.9</td>\n",
       "      <td>0.7</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Nikola Jokic</td>\n",
       "      <td>29.1</td>\n",
       "      <td>12.7</td>\n",
       "      <td>10.5</td>\n",
       "      <td>1.8</td>\n",
       "      <td>0.7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Luka Doncic</td>\n",
       "      <td>28.1</td>\n",
       "      <td>8.3</td>\n",
       "      <td>7.8</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Kevin Durant</td>\n",
       "      <td>26.7</td>\n",
       "      <td>5.9</td>\n",
       "      <td>4.3</td>\n",
       "      <td>0.9</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>Anthony Davis</td>\n",
       "      <td>26.0</td>\n",
       "      <td>16.0</td>\n",
       "      <td>7.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>Anthony Davis</td>\n",
       "      <td>25.7</td>\n",
       "      <td>11.9</td>\n",
       "      <td>3.4</td>\n",
       "      <td>1.3</td>\n",
       "      <td>2.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>Cade Cunningham</td>\n",
       "      <td>25.2</td>\n",
       "      <td>6.2</td>\n",
       "      <td>9.4</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>Karl-Anthony Towns</td>\n",
       "      <td>24.6</td>\n",
       "      <td>13.3</td>\n",
       "      <td>3.2</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>Victor Wembanyama</td>\n",
       "      <td>24.3</td>\n",
       "      <td>11.0</td>\n",
       "      <td>3.7</td>\n",
       "      <td>1.1</td>\n",
       "      <td>3.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>Zion Williamson</td>\n",
       "      <td>24.3</td>\n",
       "      <td>7.5</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1.3</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>Trae Young</td>\n",
       "      <td>23.8</td>\n",
       "      <td>3.1</td>\n",
       "      <td>11.4</td>\n",
       "      <td>1.2</td>\n",
       "      <td>0.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>49</th>\n",
       "      <td>Scottie Barnes</td>\n",
       "      <td>20.0</td>\n",
       "      <td>7.8</td>\n",
       "      <td>6.2</td>\n",
       "      <td>1.4</td>\n",
       "      <td>1.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>51</th>\n",
       "      <td>De'Aaron Fox</td>\n",
       "      <td>19.6</td>\n",
       "      <td>4.3</td>\n",
       "      <td>6.8</td>\n",
       "      <td>2.1</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>52</th>\n",
       "      <td>Domantas Sabonis</td>\n",
       "      <td>19.5</td>\n",
       "      <td>14.1</td>\n",
       "      <td>6.2</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>54</th>\n",
       "      <td>Alperen Sengun</td>\n",
       "      <td>19.1</td>\n",
       "      <td>10.6</td>\n",
       "      <td>4.8</td>\n",
       "      <td>1.1</td>\n",
       "      <td>0.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>58</th>\n",
       "      <td>Jalen Johnson</td>\n",
       "      <td>18.9</td>\n",
       "      <td>10.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>95</th>\n",
       "      <td>Ivica Zubac</td>\n",
       "      <td>15.5</td>\n",
       "      <td>12.6</td>\n",
       "      <td>2.5</td>\n",
       "      <td>0.8</td>\n",
       "      <td>1.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>117</th>\n",
       "      <td>Amen Thompson</td>\n",
       "      <td>13.9</td>\n",
       "      <td>8.2</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1.4</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>118</th>\n",
       "      <td>Dyson Daniels</td>\n",
       "      <td>13.9</td>\n",
       "      <td>5.6</td>\n",
       "      <td>4.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>0.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>153</th>\n",
       "      <td>Tari Eason</td>\n",
       "      <td>11.6</td>\n",
       "      <td>6.2</td>\n",
       "      <td>1.2</td>\n",
       "      <td>1.9</td>\n",
       "      <td>0.9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>158</th>\n",
       "      <td>Walker Kessler</td>\n",
       "      <td>11.4</td>\n",
       "      <td>12.1</td>\n",
       "      <td>1.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>2.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>169</th>\n",
       "      <td>Isaiah Hartenstein</td>\n",
       "      <td>10.9</td>\n",
       "      <td>11.4</td>\n",
       "      <td>3.9</td>\n",
       "      <td>0.8</td>\n",
       "      <td>1.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>267</th>\n",
       "      <td>Jusuf Nurkic</td>\n",
       "      <td>8.2</td>\n",
       "      <td>8.6</td>\n",
       "      <td>4.6</td>\n",
       "      <td>1.4</td>\n",
       "      <td>1.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>395</th>\n",
       "      <td>Taylor Hendricks</td>\n",
       "      <td>4.7</td>\n",
       "      <td>5.0</td>\n",
       "      <td>0.7</td>\n",
       "      <td>1.7</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                        NAME   PpG   RpG   ApG  SpG  BpG\n",
       "0    Shai Gilgeous-Alexander  32.3   5.2   6.1  1.9  1.0\n",
       "1      Giannis Antetokounmpo  30.9  12.1   5.9  0.7  1.3\n",
       "2               Nikola Jokic  29.1  12.7  10.5  1.8  0.7\n",
       "3                Luka Doncic  28.1   8.3   7.8  2.0  0.4\n",
       "7               Kevin Durant  26.7   5.9   4.3  0.9  1.3\n",
       "11             Anthony Davis  26.0  16.0   7.0  0.0  3.0\n",
       "12             Anthony Davis  25.7  11.9   3.4  1.3  2.1\n",
       "14           Cade Cunningham  25.2   6.2   9.4  1.0  0.8\n",
       "19        Karl-Anthony Towns  24.6  13.3   3.2  1.0  0.8\n",
       "20         Victor Wembanyama  24.3  11.0   3.7  1.1  3.8\n",
       "22           Zion Williamson  24.3   7.5   5.0  1.3  1.0\n",
       "28                Trae Young  23.8   3.1  11.4  1.2  0.2\n",
       "49            Scottie Barnes  20.0   7.8   6.2  1.4  1.1\n",
       "51              De'Aaron Fox  19.6   4.3   6.8  2.1  0.5\n",
       "52          Domantas Sabonis  19.5  14.1   6.2  0.6  0.4\n",
       "54            Alperen Sengun  19.1  10.6   4.8  1.1  0.8\n",
       "58             Jalen Johnson  18.9  10.0   5.0  1.6  1.0\n",
       "95               Ivica Zubac  15.5  12.6   2.5  0.8  1.2\n",
       "117            Amen Thompson  13.9   8.2   3.5  1.4  1.3\n",
       "118            Dyson Daniels  13.9   5.6   4.0  3.0  0.8\n",
       "153               Tari Eason  11.6   6.2   1.2  1.9  0.9\n",
       "158           Walker Kessler  11.4  12.1   1.6  0.6  2.3\n",
       "169       Isaiah Hartenstein  10.9  11.4   3.9  0.8  1.1\n",
       "267             Jusuf Nurkic   8.2   8.6   4.6  1.4  1.2\n",
       "395         Taylor Hendricks   4.7   5.0   0.7  1.7  1.3"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def is_dominated_5d(p1, p2):\n",
    "    return all(p1[dim] <= p2[dim] for dim in ['PpG', 'RpG', 'ApG', 'SpG', 'BpG']) and any(p1[dim] < p2[dim] for dim in ['PpG', 'RpG', 'ApG', 'SpG', 'BpG'])\n",
    "\n",
    "skyline_5d = []\n",
    "\n",
    "for _, player in df.iterrows():\n",
    "    dominated = False\n",
    "    to_remove = []\n",
    "    for s in skyline_5d:\n",
    "        if is_dominated_5d(player, s):\n",
    "            dominated = True\n",
    "            break\n",
    "        if is_dominated_5d(s, player):\n",
    "            to_remove.append(s)\n",
    "    if not dominated:\n",
    "        skyline_5d.append(player)\n",
    "        for s in to_remove:\n",
    "            skyline_5d.remove(s)\n",
    "\n",
    "skyline_5d_df = pd.DataFrame(skyline_5d)\n",
    "skyline_5d_df[['NAME', 'PpG', 'RpG', 'ApG', 'SpG', 'BpG']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task 4: Identifying the top 5 players based on domination count in 5 dimensions, PTS, REB, AST, STL, and BLK. (10%)\n",
    "- The domination count is defined as the number of points that are dominated by a point;\n",
    "- For instance, there are 3 players of 3 dimensional values (higher is better): [10,20,30], [5,7,8] and [4,10,11]. The domination count for [10,20,30] is 2 and the domination count for [4,10,11] is 0."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>NAME</th>\n",
       "      <th>PpG</th>\n",
       "      <th>RpG</th>\n",
       "      <th>ApG</th>\n",
       "      <th>SpG</th>\n",
       "      <th>BpG</th>\n",
       "      <th>domination_count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Nikola Jokic</td>\n",
       "      <td>29.1</td>\n",
       "      <td>12.7</td>\n",
       "      <td>10.5</td>\n",
       "      <td>1.8</td>\n",
       "      <td>0.7</td>\n",
       "      <td>509</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>49</th>\n",
       "      <td>Scottie Barnes</td>\n",
       "      <td>20.0</td>\n",
       "      <td>7.8</td>\n",
       "      <td>6.2</td>\n",
       "      <td>1.4</td>\n",
       "      <td>1.1</td>\n",
       "      <td>486</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>58</th>\n",
       "      <td>Jalen Johnson</td>\n",
       "      <td>18.9</td>\n",
       "      <td>10.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>483</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>Zion Williamson</td>\n",
       "      <td>24.3</td>\n",
       "      <td>7.5</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1.3</td>\n",
       "      <td>1.0</td>\n",
       "      <td>475</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Shai Gilgeous-Alexander</td>\n",
       "      <td>32.3</td>\n",
       "      <td>5.2</td>\n",
       "      <td>6.1</td>\n",
       "      <td>1.9</td>\n",
       "      <td>1.0</td>\n",
       "      <td>471</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                       NAME   PpG   RpG   ApG  SpG  BpG  domination_count\n",
       "2              Nikola Jokic  29.1  12.7  10.5  1.8  0.7               509\n",
       "49           Scottie Barnes  20.0   7.8   6.2  1.4  1.1               486\n",
       "58            Jalen Johnson  18.9  10.0   5.0  1.6  1.0               483\n",
       "22          Zion Williamson  24.3   7.5   5.0  1.3  1.0               475\n",
       "0   Shai Gilgeous-Alexander  32.3   5.2   6.1  1.9  1.0               471"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def domination_count(player, df):\n",
    "    count = 0\n",
    "    for _, other in df.iterrows():\n",
    "        if all(player[dim] >= other[dim] for dim in ['PpG', 'RpG', 'ApG', 'SpG', 'BpG']) and any(player[dim] > other[dim] for dim in ['PpG', 'RpG', 'ApG', 'SpG', 'BpG']):\n",
    "            count += 1\n",
    "    return count\n",
    "\n",
    "df['domination_count'] = df.apply(lambda player: domination_count(player, df), axis=1)\n",
    "top_5_players = df.sort_values(by='domination_count', ascending=False).head(5)\n",
    "top_5_players[['NAME', 'PpG', 'RpG', 'ApG', 'SpG', 'BpG', 'domination_count']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task 5: Revisiting the implementation (10%)\n",
    "- Without constructing the multi-dimensional index, do you have any ideas for improving the implementation in Task 2 and Task 3? Please explain your approach and the reasoning behind it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>NAME</th>\n",
       "      <th>PpG</th>\n",
       "      <th>RpG</th>\n",
       "      <th>ApG</th>\n",
       "      <th>SpG</th>\n",
       "      <th>BpG</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Shai Gilgeous-Alexander</td>\n",
       "      <td>32.3</td>\n",
       "      <td>5.2</td>\n",
       "      <td>6.1</td>\n",
       "      <td>1.9</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Giannis Antetokounmpo</td>\n",
       "      <td>30.9</td>\n",
       "      <td>12.1</td>\n",
       "      <td>5.9</td>\n",
       "      <td>0.7</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Nikola Jokic</td>\n",
       "      <td>29.1</td>\n",
       "      <td>12.7</td>\n",
       "      <td>10.5</td>\n",
       "      <td>1.8</td>\n",
       "      <td>0.7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Luka Doncic</td>\n",
       "      <td>28.1</td>\n",
       "      <td>8.3</td>\n",
       "      <td>7.8</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Kevin Durant</td>\n",
       "      <td>26.7</td>\n",
       "      <td>5.9</td>\n",
       "      <td>4.3</td>\n",
       "      <td>0.9</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>Anthony Davis</td>\n",
       "      <td>26.0</td>\n",
       "      <td>16.0</td>\n",
       "      <td>7.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>Anthony Davis</td>\n",
       "      <td>25.7</td>\n",
       "      <td>11.9</td>\n",
       "      <td>3.4</td>\n",
       "      <td>1.3</td>\n",
       "      <td>2.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>Cade Cunningham</td>\n",
       "      <td>25.2</td>\n",
       "      <td>6.2</td>\n",
       "      <td>9.4</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>Karl-Anthony Towns</td>\n",
       "      <td>24.6</td>\n",
       "      <td>13.3</td>\n",
       "      <td>3.2</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>Victor Wembanyama</td>\n",
       "      <td>24.3</td>\n",
       "      <td>11.0</td>\n",
       "      <td>3.7</td>\n",
       "      <td>1.1</td>\n",
       "      <td>3.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>Zion Williamson</td>\n",
       "      <td>24.3</td>\n",
       "      <td>7.5</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1.3</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>Trae Young</td>\n",
       "      <td>23.8</td>\n",
       "      <td>3.1</td>\n",
       "      <td>11.4</td>\n",
       "      <td>1.2</td>\n",
       "      <td>0.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>49</th>\n",
       "      <td>Scottie Barnes</td>\n",
       "      <td>20.0</td>\n",
       "      <td>7.8</td>\n",
       "      <td>6.2</td>\n",
       "      <td>1.4</td>\n",
       "      <td>1.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>51</th>\n",
       "      <td>De'Aaron Fox</td>\n",
       "      <td>19.6</td>\n",
       "      <td>4.3</td>\n",
       "      <td>6.8</td>\n",
       "      <td>2.1</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>52</th>\n",
       "      <td>Domantas Sabonis</td>\n",
       "      <td>19.5</td>\n",
       "      <td>14.1</td>\n",
       "      <td>6.2</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>54</th>\n",
       "      <td>Alperen Sengun</td>\n",
       "      <td>19.1</td>\n",
       "      <td>10.6</td>\n",
       "      <td>4.8</td>\n",
       "      <td>1.1</td>\n",
       "      <td>0.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>58</th>\n",
       "      <td>Jalen Johnson</td>\n",
       "      <td>18.9</td>\n",
       "      <td>10.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>95</th>\n",
       "      <td>Ivica Zubac</td>\n",
       "      <td>15.5</td>\n",
       "      <td>12.6</td>\n",
       "      <td>2.5</td>\n",
       "      <td>0.8</td>\n",
       "      <td>1.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>117</th>\n",
       "      <td>Amen Thompson</td>\n",
       "      <td>13.9</td>\n",
       "      <td>8.2</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1.4</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>118</th>\n",
       "      <td>Dyson Daniels</td>\n",
       "      <td>13.9</td>\n",
       "      <td>5.6</td>\n",
       "      <td>4.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>0.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>153</th>\n",
       "      <td>Tari Eason</td>\n",
       "      <td>11.6</td>\n",
       "      <td>6.2</td>\n",
       "      <td>1.2</td>\n",
       "      <td>1.9</td>\n",
       "      <td>0.9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>158</th>\n",
       "      <td>Walker Kessler</td>\n",
       "      <td>11.4</td>\n",
       "      <td>12.1</td>\n",
       "      <td>1.6</td>\n",
       "      <td>0.6</td>\n",
       "      <td>2.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>169</th>\n",
       "      <td>Isaiah Hartenstein</td>\n",
       "      <td>10.9</td>\n",
       "      <td>11.4</td>\n",
       "      <td>3.9</td>\n",
       "      <td>0.8</td>\n",
       "      <td>1.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>267</th>\n",
       "      <td>Jusuf Nurkic</td>\n",
       "      <td>8.2</td>\n",
       "      <td>8.6</td>\n",
       "      <td>4.6</td>\n",
       "      <td>1.4</td>\n",
       "      <td>1.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>395</th>\n",
       "      <td>Taylor Hendricks</td>\n",
       "      <td>4.7</td>\n",
       "      <td>5.0</td>\n",
       "      <td>0.7</td>\n",
       "      <td>1.7</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                        NAME   PpG   RpG   ApG  SpG  BpG\n",
       "0    Shai Gilgeous-Alexander  32.3   5.2   6.1  1.9  1.0\n",
       "1      Giannis Antetokounmpo  30.9  12.1   5.9  0.7  1.3\n",
       "2               Nikola Jokic  29.1  12.7  10.5  1.8  0.7\n",
       "3                Luka Doncic  28.1   8.3   7.8  2.0  0.4\n",
       "7               Kevin Durant  26.7   5.9   4.3  0.9  1.3\n",
       "11             Anthony Davis  26.0  16.0   7.0  0.0  3.0\n",
       "12             Anthony Davis  25.7  11.9   3.4  1.3  2.1\n",
       "14           Cade Cunningham  25.2   6.2   9.4  1.0  0.8\n",
       "19        Karl-Anthony Towns  24.6  13.3   3.2  1.0  0.8\n",
       "20         Victor Wembanyama  24.3  11.0   3.7  1.1  3.8\n",
       "22           Zion Williamson  24.3   7.5   5.0  1.3  1.0\n",
       "28                Trae Young  23.8   3.1  11.4  1.2  0.2\n",
       "49            Scottie Barnes  20.0   7.8   6.2  1.4  1.1\n",
       "51              De'Aaron Fox  19.6   4.3   6.8  2.1  0.5\n",
       "52          Domantas Sabonis  19.5  14.1   6.2  0.6  0.4\n",
       "54            Alperen Sengun  19.1  10.6   4.8  1.1  0.8\n",
       "58             Jalen Johnson  18.9  10.0   5.0  1.6  1.0\n",
       "95               Ivica Zubac  15.5  12.6   2.5  0.8  1.2\n",
       "117            Amen Thompson  13.9   8.2   3.5  1.4  1.3\n",
       "118            Dyson Daniels  13.9   5.6   4.0  3.0  0.8\n",
       "153               Tari Eason  11.6   6.2   1.2  1.9  0.9\n",
       "158           Walker Kessler  11.4  12.1   1.6  0.6  2.3\n",
       "169       Isaiah Hartenstein  10.9  11.4   3.9  0.8  1.1\n",
       "267             Jusuf Nurkic   8.2   8.6   4.6  1.4  1.2\n",
       "395         Taylor Hendricks   4.7   5.0   0.7  1.7  1.3"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "def pareto_front(df, dimensions):\n",
    "    is_dominated = np.zeros(len(df), dtype=bool)\n",
    "    for i, player in df.iterrows():\n",
    "        if not is_dominated[i]:\n",
    "            is_dominated |= (df[dimensions] <= player[dimensions]).all(axis=1) & (df[dimensions] < player[dimensions]).any(axis=1)\n",
    "            is_dominated[i] = False\n",
    "    return df[~is_dominated]\n",
    "\n",
    "# Task 2: Find the skyline players using PTS, REB, and AST\n",
    "skyline_3d = pareto_front(df, ['PpG', 'RpG', 'ApG'])\n",
    "skyline_3d[['NAME', 'PpG', 'RpG', 'ApG']]\n",
    "\n",
    "# Task 3: Find the skyline players using PTS, REB, AST, STL, and BLK\n",
    "skyline_5d = pareto_front(df, ['PpG', 'RpG', 'ApG', 'SpG', 'BpG'])\n",
    "skyline_5d[['NAME', 'PpG', 'RpG', 'ApG', 'SpG', 'BpG']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "cisc7021",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
